// DrawerExample.js

'use strict';

import React, {Component} from 'react';
import {View, ScrollView, Image, Text} from 'react-native';

import {Theme, NavigationPage, ListRow, Drawer, Button, Label, Overlay, Toast, Input} from 'teaset';
import SelectRow from './SelectRow';

export default class DrawerExample extends NavigationPage {

  static defaultProps = {
    ...NavigationPage.defaultProps,
    title: 'Drawer',
    showBackButton: true,
  };

  constructor(props) {
    super(props);
    Object.assign(this.state, {
      rootTransform: 'none',
      eventLog: [],
    });
    this.drawerViewController = null;
    this.drawerDemoTimeout = null;
    this.drawerDemoRefs = {
      sideLeft: React.createRef(),
      sideRight: React.createRef(),
      sideTop: React.createRef(),
      sideBottom: React.createRef(),
      rootNone: React.createRef(),
      rootTranslate: React.createRef(),
      rootScale: React.createRef(),
      pointerAuto: React.createRef(),
      pointerNone: React.createRef(),
      opacityClear: React.createRef(),
      opacityMasked: React.createRef(),
      modalTrue: React.createRef(),
      modalFalse: React.createRef(),
      animatedTrue: React.createRef(),
      animatedFalse: React.createRef(),
      styleCustom: React.createRef(),
      containerStyleCustom: React.createRef(),
      autoKeyboardTrue: React.createRef(),
      autoKeyboardFalse: React.createRef(),
    };
  }

  componentWillUnmount() {
    if (this.drawer) {
      this.drawer.close();
      this.drawer = null;
    }
    if (this.drawerViewController) {
      this.drawerViewController.close(false);
      this.drawerViewController = null;
    }
    if (this.drawerDemoTimeout) {
      clearTimeout(this.drawerDemoTimeout);
      this.drawerDemoTimeout = null;
    }
  }

  show(side) {
    let {rootTransform} = this.state;
    if (side == 'left' || side == 'right') {
      this.drawer = Drawer.open(this.renderDrawerMenu(), side, rootTransform);
    } else {
      this.drawer = Drawer.open(this.renderDrawerBox(side), side, rootTransform, {containerStyle: {backgroundColor: 'rgba(0, 0, 0, 0)'}});
    }
  }

  renderDrawerMenu() {
    return (
      <View style={{backgroundColor: Theme.defaultColor, width: 260, flex: 1}}>
        <View style={{height: 60}} />
        <ListRow
          icon={
            <View style={{paddingRight: 12}}>
              <Image style={{width: 30, height: 30, tintColor: Theme.primaryColor}} source={require('../icons/me_active.png')} />
            </View>
          }
          title='User name'
          />
        <ListRow
          icon={require('../icons/home_active.png')}
          title='Home'
          />
        <ListRow
          icon={require('../icons/store_active.png')}
          title='Store'
          bottomSeparator='none'
          />
        <View style={{flex: 1}} />
        <Button type='link' size='sm' title='Hide' onPress={() => this.drawer && this.drawer.close()} />
      </View>
    );
  }

  renderDrawerBox(side) {
    return (
      <View style={{
        height: 290,
        justifyContent: side == 'top' ? 'flex-start' : 'flex-end',
      }}>
        <View style={{backgroundColor: Theme.defaultColor, height: 260}}>
          <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
            <Label type='detail' size='xl' text='Drawer' />
          </View>
        </View>
        <Image
          style={{
            position: 'absolute',
            top: side == 'bottom' ? 0 : undefined,
            bottom: side == 'top' ? 0 : undefined,
            left: 12,
            width: 60,
            height: 60,
            borderRadius: 30
          }}
          source={require('../images/faircup.jpg')}
          />
      </View>
    );
  }

  renderDrawerViewContent(side, onClose) {
    let {rootTransform} = this.state;
    let isHorizontal = side === 'left' || side === 'right';
    let containerStyle = {
      backgroundColor: Theme.defaultColor,
      paddingHorizontal: 20,
      paddingVertical: 24,
      justifyContent: 'space-between',
    };
    if (isHorizontal) {
      Object.assign(containerStyle, {width: 280, flex: 1});
    } else {
      Object.assign(containerStyle, {height: 260, alignSelf: 'stretch'});
    }
    return (
      <View style={containerStyle}>
        <View>
          <Label type='detail' size='lg' text='Drawer.DrawerView Demo' style={{fontWeight: 'bold', color: '#333'}} />
          <View style={{height: 8}} />
          <Text style={{color: '#666', fontSize: 13}}>当前打开侧：{side}</Text>
          <Text style={{color: '#666', fontSize: 13, marginTop: 4}}>rootTransform：{rootTransform}</Text>
          <Text style={{color: '#999', fontSize: 12, marginTop: 6}}>通过直接使用 Drawer.DrawerView，可以自定义内容布局、尺寸和关闭行为。</Text>
        </View>
        <View>
          <Button
            title='关闭抽屉'
            type='secondary'
            onPress={onClose}
          />
        </View>
      </View>
    );
  }

  clearDrawerDemoTimeout() {
    if (this.drawerDemoTimeout) {
      clearTimeout(this.drawerDemoTimeout);
      this.drawerDemoTimeout = null;
    }
  }

  formatEventTimestamp(date) {
    const pad = value => value.toString().padStart(2, '0');
    return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
  }

  logDrawerEvent(event, detail = '') {
    const entry = {event, timestamp: this.formatEventTimestamp(new Date())};
    this.setState(prevState => {
      const history = prevState.eventLog ? prevState.eventLog.slice(0, 7) : [];
      return {eventLog: [entry, ...history]};
    });
    const message = detail ? `${event}: ${detail}` : event;
    Toast.message(message, {position: 'top', duration: 1600});
  }

  renderDrawerDemoContent(drawerProps, onClose, additionalNotes = [], keyboardDemo = false) {
    const rows = [
      `side: ${drawerProps.side ?? 'bottom'}`,
      `rootTransform: ${Array.isArray(drawerProps.rootTransform) ? 'custom array' : (drawerProps.rootTransform ?? 'none')}`,
      `modal: ${drawerProps.modal ? 'true' : 'false'}`,
      `overlayOpacity: ${typeof drawerProps.overlayOpacity === 'number' ? drawerProps.overlayOpacity : 'Theme 默认'}`,
      `overlayPointerEvents: ${drawerProps.overlayPointerEvents ?? 'auto'}`,
      `animated: ${drawerProps.animated === false ? 'false' : 'true (默认)'}`,
      `style: ${drawerProps.style ? '自定义' : '默认'}`,
      `containerStyle: ${drawerProps.containerStyle ? '自定义' : '默认'}`,
      `autoKeyboardInsets: ${drawerProps.autoKeyboardInsets === true ? 'true' : (drawerProps.autoKeyboardInsets === false ? 'false' : '默认(false)')}`,
    ];

    // Determine sizing for drawer content so top/bottom drawers have a fixed height
    const side = drawerProps.side || 'bottom';
    const isHorizontal = side === 'left' || side === 'right';
    const hasCustomContainerStyle = !!drawerProps.containerStyle;
    let containerStyle = {
      paddingHorizontal: 20,
      paddingVertical: 24,
      justifyContent: keyboardDemo ? 'flex-start' : 'space-between',
      backgroundColor: hasCustomContainerStyle ? 'transparent' : Theme.defaultColor,
    };
    if (isHorizontal) {
      Object.assign(containerStyle, {width: 280});
    } else {
      Object.assign(containerStyle, {
        alignSelf: 'stretch',
        minHeight: keyboardDemo ? 340 : 260,
      });
    }

    return (
      <View style={containerStyle}>
        <View>
          <Label type='detail' size='lg' text='Drawer.DrawerView 属性示例' style={{fontWeight: 'bold', color: '#333'}} />
          <View style={{height: 8}} />
          {rows.map(item => (
            <Text key={item} style={{color: '#666', fontSize: 13, marginTop: 2}}>{item}</Text>
          ))}
          {additionalNotes.length ? (
            <View style={{marginTop: 10}}>
              {additionalNotes.map(note => (
                <Text key={note} style={{color: '#999', fontSize: 12, marginTop: 2}}>{note}</Text>
              ))}
            </View>
          ) : null}
        </View>
        <View style={{marginTop: keyboardDemo ? 16 : 0}}>
          {keyboardDemo ? (
            <View>
              <Label type='detail' size='sm' text='键盘示例区' style={{color: '#444'}} />
              <Text style={{color: '#999', fontSize: 12, marginTop: 4}}>聚焦输入框观察 autoKeyboardInsets 对抽屉内容的位置影响。</Text>
              <Input
                size='md'
                style={{marginTop: 10, height: 40}}
                placeholder='在此输入一些文字'
                clearButtonMode='while-editing'
              />
              <Input
                size='md'
                style={{marginTop: 10, height: 40}}
                placeholder='再来一个输入框用于对比'
                clearButtonMode='while-editing'
              />
              <View style={{height: 12}} />
            </View>
          ) : null}
          <Button title='关闭抽屉' type='secondary' onPress={onClose} style={{marginTop: keyboardDemo ? 4 : 0}} />
        </View>
      </View>
    );
  }

  showDrawerViewDemo(buttonRef, options = {}) {
    const target = buttonRef && buttonRef.current;
    if (!target) {
      return;
    }
    const {
      description,
      autoHideDuration,
      additionalNotes = [],
      keyboardDemo = false,
      onAppearCompleted: userOnAppearCompleted,
      onCloseRequest: userOnCloseRequest,
      onDisappearCompleted: userOnDisappearCompleted,
      ...drawerProps
    } = options;

    if (this.drawerViewController) {
      this.drawerViewController.close(false);
      this.drawerViewController = null;
    }

    const sideLabel = drawerProps.side ?? 'bottom';
    let drawerRef = null;
    let overlayKey = null;

    const closeDrawer = (animated) => {
      if (drawerRef && !drawerRef.closed) {
        drawerRef.close(animated);
      } else if (overlayKey) {
        Overlay.hide(overlayKey);
      }
    };

    overlayKey = Overlay.show(
      <Drawer.DrawerView
        {...drawerProps}
        ref={ref => drawerRef = ref}
        onAppearCompleted={() => {
          this.logDrawerEvent('Drawer.DrawerView onAppearCompleted', `side=${sideLabel}`);
          userOnAppearCompleted && userOnAppearCompleted();
        }}
        onCloseRequest={overlayInstance => {
          this.logDrawerEvent('Drawer.DrawerView onCloseRequest', `side=${sideLabel}`);
          if (userOnCloseRequest) {
            const result = userOnCloseRequest(overlayInstance);
            if (result === false) {
              return false;
            }
          }
          if (drawerProps.modal) {
            Toast.message('modal = true，点击遮罩不会关闭，请使用内容按钮关闭。', {position: 'top', duration: 1600});
            return false;
          }
          closeDrawer();
          return true;
        }}
        onDisappearCompleted={() => {
          this.logDrawerEvent('Drawer.DrawerView onDisappearCompleted', `side=${sideLabel}`);
          userOnDisappearCompleted && userOnDisappearCompleted();
          if (this.drawerViewController && this.drawerViewController.key === overlayKey) {
            this.drawerViewController = null;
          }
          this.clearDrawerDemoTimeout();
        }}
      >
        {this.renderDrawerDemoContent(drawerProps, () => {
          this.logDrawerEvent('Drawer.DrawerView 手动关闭', `side=${sideLabel}`);
          closeDrawer();
        }, additionalNotes, keyboardDemo)}
      </Drawer.DrawerView>
    );

    this.drawerViewController = {
      key: overlayKey,
      close: (animated) => {
        closeDrawer(animated);
      },
    };

    if (description) {
      Toast.message(description, {position: 'top', duration: 1600});
    }

    this.clearDrawerDemoTimeout();
    const timeout = autoHideDuration ?? (drawerProps.overlayPointerEvents === 'none' ? 2200 : null);
    if (timeout) {
      this.drawerDemoTimeout = setTimeout(() => {
        if (this.drawerViewController && this.drawerViewController.key === overlayKey) {
          this.drawerViewController.close();
        }
        this.clearDrawerDemoTimeout();
      }, timeout);
    }
  }

  renderPage() {
    let {rootTransform, eventLog = []} = this.state;
    return (
      <ScrollView style={{flex: 1}}>
        <View style={{height: 20}} />
        <View style={{marginHorizontal: 12, padding: 12, borderRadius: 8, borderWidth: 1, borderColor: '#b3e5fc', backgroundColor: '#e1f5fe'}}>
          <Label style={{fontSize: 12, fontWeight: 'bold', color: '#0277bd'}} text='最近抽屉事件' />
          {eventLog.length ? (
            eventLog.slice(0, 3).map((item, index) => (
              <Text
                key={`${item.event}-${item.timestamp || index}`}
                style={{marginTop: 6, fontSize: 12, color: '#01579b'}}
              >
                {`事件${index + 1}：${item.event}（${item.timestamp || '-'}）`}
              </Text>
            ))
          ) : (
            <Text style={{marginTop: 6, fontSize: 12, color: '#01579b'}}>暂无事件</Text>
          )}
        </View>
        <View style={{height: 16}} />
        
        <Label type='detail' size='md' text=' side 拉出边' style={{ fontWeight: 'bold', color: '#000' }}/>
        <View style={{height: 10}} />
        <Text style={{marginLeft: 20, marginRight: 20, color: '#999', fontSize: 12, lineHeight: 18}}>
          side 属性演示 - 控制抽屉从哪一侧拉出 (left/right/top/bottom)
        </Text>
        <ListRow title='Left side' onPress={() => this.show('left')} topSeparator='full' />
        <ListRow title='Right side' onPress={() => this.show('right')} />
        <ListRow title='Top side' onPress={() => this.show('top')} />
        <ListRow title='Bottom side' onPress={() => this.show('bottom')} bottomSeparator='full'/>
        
        <View style={{height: 20}} />
        <Label type='detail' size='md' text=' rootTransform 根组件转换动画' style={{ fontWeight: 'bold', color: '#000' }}/>
        <View style={{height: 10}} />
        <Text style={{marginLeft: 20, marginRight: 20, color: '#999', fontSize: 12, lineHeight: 18}}>
          rootTransform 属性演示 - 选择根视图随抽屉的动画 (none/translate/scale)
        </Text>
        <SelectRow
          title='Root transform'
          value={rootTransform}
          items={['none', 'translate', 'scale']}
          onSelected={(item, index) => this.setState({rootTransform: item})}
          topSeparator='full'
          bottomSeparator='full'
          />
        
        <View style={{height: 28}} />
        <Label type='detail' size='md' text='Drawer.DrawerView 直接用法 (覆盖枚举)' style={{ fontWeight: 'bold', color: '#000' }}/>
        <View style={{height: 10}} />
        <Text style={{marginLeft: 20, marginRight: 20, color: '#999', fontSize: 12, lineHeight: 18}}>
          下列按钮直接创建 Drawer.DrawerView，分别演示 side、rootTransform、overlayOpacity、overlayPointerEvents、modal 与 animated 等继承属性。
        </Text>

        <View style={{height: 18}} />
        <Label type='detail' size='sm' text='side (left / right / top / bottom)' style={{marginLeft: 20}} />
        <View style={{height: 10}} />
        <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
          <Button title='side: left' ref={this.drawerDemoRefs.sideLeft} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.sideLeft, {side: 'left', description: 'Drawer.DrawerView side = left'})} />
          <Button title='side: right' ref={this.drawerDemoRefs.sideRight} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.sideRight, {side: 'right', description: 'Drawer.DrawerView side = right'})} />
        </View>
        <View style={{height: 10}} />
        <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
          <Button title='side: top' ref={this.drawerDemoRefs.sideTop} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.sideTop, {side: 'top', description: 'Drawer.DrawerView side = top'})} />
          <Button title='side: bottom' ref={this.drawerDemoRefs.sideBottom} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.sideBottom, {side: 'bottom', description: 'Drawer.DrawerView side = bottom'})} />
        </View>

        <View style={{height: 22}} />
        <Label type='detail' size='sm' text='rootTransform (none / translate / scale)' style={{marginLeft: 20}} />
        <View style={{height: 10}} />
        <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
          <Button title='root: none' ref={this.drawerDemoRefs.rootNone} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.rootNone, {side: 'left', rootTransform: 'none', description: 'Drawer.DrawerView rootTransform = none'})} />
          <Button title='root: translate' ref={this.drawerDemoRefs.rootTranslate} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.rootTranslate, {side: 'left', rootTransform: 'translate', description: 'Drawer.DrawerView rootTransform = translate', additionalNotes: ['根视图会随抽屉平移。']})} />
          <Button title='root: scale' ref={this.drawerDemoRefs.rootScale} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.rootScale, {side: 'left', rootTransform: 'scale', description: 'Drawer.DrawerView rootTransform = scale', additionalNotes: ['根视图缩小，突出抽屉。']})} />
        </View>

        <View style={{height: 22}} />
        <Label type='detail' size='sm' text='overlayOpacity (0 / 0.45)' style={{marginLeft: 20}} />
        <View style={{height: 10}} />
        <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
          <Button title='overlayOpacity: 0' ref={this.drawerDemoRefs.opacityClear} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.opacityClear, {side: 'bottom', overlayOpacity: 0, description: 'Drawer.DrawerView overlayOpacity = 0 (无遮罩)'})} />
          <Button title='overlayOpacity: 0.45' ref={this.drawerDemoRefs.opacityMasked} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.opacityMasked, {side: 'bottom', overlayOpacity: 0.45, description: 'Drawer.DrawerView overlayOpacity = 0.45 (半透明遮罩)'})} />
        </View>

        <View style={{height: 22}} />
        <Label type='detail' size='sm' text='overlayPointerEvents (auto / none)' style={{marginLeft: 20}} />
        <View style={{height: 10}} />
        <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
          <Button title='pointerEvents: auto' ref={this.drawerDemoRefs.pointerAuto} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.pointerAuto, {side: 'right', overlayPointerEvents: 'auto', description: 'Drawer.DrawerView overlayPointerEvents = auto (遮罩拦截触摸)'})} />
          <Button title='pointerEvents: none' ref={this.drawerDemoRefs.pointerNone} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.pointerNone, {side: 'right', overlayPointerEvents: 'none', description: 'Drawer.DrawerView overlayPointerEvents = none (触摸穿透，自动关闭)', additionalNotes: ['遮罩不拦截触摸，示例 2.2 秒后自动关闭。']})} />
        </View>

        <View style={{height: 22}} />
        <Label type='detail' size='sm' text='autoKeyboardInsets (true / false)' style={{marginLeft: 20}} />
        <View style={{height: 10}} />
        <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
          <Button
            title='autoKeyboardInsets: true'
            ref={this.drawerDemoRefs.autoKeyboardTrue}
            onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.autoKeyboardTrue, {
              side: 'bottom',
              autoKeyboardInsets: true,
              keyboardDemo: true,
              description: 'Drawer.DrawerView autoKeyboardInsets = true (键盘弹出时自动空出空间)',
              additionalNotes: ['聚焦输入框时抽屉内容会自动上移以避开键盘。']
            })}
          />
          <Button
            title='autoKeyboardInsets: false'
            ref={this.drawerDemoRefs.autoKeyboardFalse}
            onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.autoKeyboardFalse, {
              side: 'bottom',
              autoKeyboardInsets: false,
              keyboardDemo: true,
              description: 'Drawer.DrawerView autoKeyboardInsets = false (不处理键盘遮挡)',
              additionalNotes: ['聚焦输入框时可以看到键盘遮挡效果。']
            })}
          />
        </View>

        <View style={{height: 22}} />
        <Label type='detail' size='sm' text='modal (true: 需手动关闭)' style={{marginLeft: 20}} />
        <View style={{height: 10}} />
        <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
          <Button title='modal: true 示例' ref={this.drawerDemoRefs.modalTrue} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.modalTrue, {side: 'bottom', modal: true, overlayOpacity: 0.45, description: 'Drawer.DrawerView modal = true (点击遮罩不会关闭)', additionalNotes: ['遮罩区域点击时不会消失，请使用内容按钮关闭。']})} />
          <Button title='modal: false 示例' ref={this.drawerDemoRefs.modalFalse} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.modalFalse, {side: 'bottom', modal: false, overlayOpacity: 0.45, description: 'Drawer.DrawerView modal = false (点击遮罩可关闭)', additionalNotes: ['默认模式，点击遮罩区域会触发关闭。']})} />
        </View>

        <View style={{height: 22}} />
        <Label type='detail' size='sm' text='animated (true / false)' style={{marginLeft: 20}} />
        <View style={{height: 10}} />
        <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
          <Button title='animated: true' ref={this.drawerDemoRefs.animatedTrue} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.animatedTrue, {side: 'top', animated: true, description: 'Drawer.DrawerView animated = true (默认动画)'})} />
          <Button title='animated: false' ref={this.drawerDemoRefs.animatedFalse} onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.animatedFalse, {side: 'top', animated: false, description: 'Drawer.DrawerView animated = false (无动画)', additionalNotes: ['抽屉立即出现与消失，便于观察差异。']})} />
        </View>

        <View style={{height: 22}} />
        <Label type='detail' size='sm' text='style / containerStyle 自定义' style={{marginLeft: 20}} />
        <View style={{height: 10}} />
        <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
          <Button
            title='style: 内边距对齐'
            ref={this.drawerDemoRefs.styleCustom}
            onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.styleCustom, {
              side: 'bottom',
              style: {justifyContent: 'flex-end', alignItems: 'center', paddingBottom: 32, paddingHorizontal: 16},
              description: 'Drawer.DrawerView style = 自定义 (控制浮层外层布局)',
              additionalNotes: ['style 属性可以调整浮层自身的对齐方式与内边距。']
            })}
          />
          <Button
            title='containerStyle: 圆角'
            ref={this.drawerDemoRefs.containerStyleCustom}
            onPress={() => this.showDrawerViewDemo(this.drawerDemoRefs.containerStyleCustom, {
              side: 'bottom',
              containerStyle: {
                borderTopLeftRadius: 18,
                borderTopRightRadius: 18,
                paddingHorizontal: 0,
                paddingBottom: 24,
                backgroundColor: Theme.defaultColor,
                overflow: 'hidden',
              },
              description: 'Drawer.DrawerView containerStyle = 自定义 (调整抽屉面板外观)',
              additionalNotes: ['containerStyle 可设置抽屉面板圆角或阴影等视觉效果。']
            })}
          />
        </View>

        <View style={{height: 20}} />
      </ScrollView>
    );
  }

}

